/// Copyright (c) 2008-2011 Brad Williams
/// 
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
/// associated documentation files (the "Software"), to deal in the Software without restriction,
/// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
/// subject to the following conditions:
/// 
/// The above copyright notice and this permission notice shall be included in all copies or substantial
/// portions of the Software.
/// 
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
/// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
/// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
/// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration.Provider;
using System.IO;
using System.Reflection;
using System.Web.Security;
using Db4objects.Db4o;
using db4oProviders;
using NUnit.Framework;

#pragma warning disable 612,618

namespace WCSoft.db4oProviders
{
    public class MockConnectionStringStore : IConnectionStringStore
    {
        public static string DBFileName = Path.GetTempFileName();

        #region IConnectionStringStore Members

        public string GetConnectionString(string connectionStringName)
        {
            return DBFileName;
        }

        #endregion
    }

    public class MockValidationKeyInfo : IValidationKeyInfo
    {
        #region IValidationKeyInfo Members

        public string GetKey()
        {
            return "abc";
        }

        public bool IsAutoGenerated()
        {
            return false;
        }

        #endregion
    }

    [TestFixture]
    public class db4oMembershipProviderTestsWhenClear
    {
        #region Setup/Teardown

        [SetUp]
        public void TestSetUp()
        {
            config = new NameValueCollection();

            config.Add("connectionStringName", "connectionstringname");
            config.Add("ApplicationName", "db4otest");
            config.Add("EnablePasswordReset", "true");
            config.Add("EnablePasswordRetrieval", "true");
            config.Add("MaxInvalidPasswordAttempts", "3");
            config.Add("MinRequiredNonAlphanumericCharacters", "0");
            config.Add("MinRequiredPasswordLength", "5");
            config.Add("PasswordAttemptWindow", "5");
            config.Add("PasswordFormat", "Clear");
            config.Add("PasswordStrengthRegularExpression", "");
            config.Add("RequiresQuestionAndAnswer", "true");
            config.Add("RequiresUniqueEmail", "true");

            connectionStringStore = new MockConnectionStringStore();
            provider = new db4oMembershipProvider(connectionStringStore, new MockValidationKeyInfo());
            provider.Initialize("db4otest", config);

            // unit test project is a library project, so web.config is ignored, so no way to specify a provider
            // instead, custom provider is forced into system using this hack found at http://gigablast.com/get?d=66151861944
            SetReadWrite();
            Membership.Providers.Add(provider);
            Membership.Providers.SetReadOnly();
        }

        [TearDown]
        public void TestTearDown()
        {
            SetReadWrite();
            Membership.Providers.Remove(provider.Name);
            Membership.Providers.SetReadOnly();
            SafeDB.DropAll();
            File.Delete(MockConnectionStringStore.DBFileName);
            provider = null;
        }

        #endregion

        private NameValueCollection config;
        private db4oMembershipProvider provider;
        private IConnectionStringStore connectionStringStore;

        private void SetReadWrite()
        {
            typeof (ProviderCollection)
                .GetField("_ReadOnly", BindingFlags.Instance | BindingFlags.NonPublic)
                .SetValue(Membership.Providers, false);
        }

        [Test]
        public void ChangePassword()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, null,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, null,
                                out status);

            bool result = provider.ChangePassword("foo", "password2", "newpassword");
            Assert.IsFalse(result, "ChangePassword should not have succeeded");

            result = provider.ChangePassword("username2", "foo", "newpassword");
            Assert.IsFalse(result, "ChangePassword should not have succeeded");

            result = provider.ChangePassword("username2", "password2", "newpassword");
            Assert.IsTrue(result, "ChangePassword failed");

            result = provider.ChangePassword("username2", "newpassword", "newnewpassword");
            Assert.IsTrue(result, "ChangePassword failed when changing password again");
        }

        [Test]
        public void ChangePasswordQuestionAndAnswer()
        {
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, guid1,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, guid2,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, guid3,
                                out status);

            bool result = provider.ChangePasswordQuestionAndAnswer("username1", "foo", "bar", "quux");
            Assert.AreEqual(false, result, "should have failed");

            result = provider.ChangePasswordQuestionAndAnswer("username1", "password1", "bar", "quux");
            Assert.AreEqual(true, result, "should have succeeded 1");

            string newPassword = provider.ResetPassword("username1", "quux");

            result = provider.ChangePasswordQuestionAndAnswer("username1", newPassword, "abc", "def");
            Assert.AreEqual(true, result, "should have succeeded 2");
        }

        [Test]
        public void CreateUser()
        {
            MembershipCreateStatus status;
            MembershipUser m =
                provider.CreateUser("username", "password", "email@email.com", "passwordQ1", "passwordA1", true, null,
                                    out status);
            Assert.AreEqual(MembershipCreateStatus.Success, status, "status not Success");
            Assert.AreEqual("username", m.UserName, "wrong Username");
            Assert.AreEqual("email@email.com", m.Email, "wrong Email");
            Assert.AreEqual(true, m.IsApproved, "wrong IsApproved");
            Assert.AreEqual("passwordQ1", m.PasswordQuestion, "wrong PasswordQuestion");
            Assert.IsNotNull(m.ProviderUserKey, "ProviderUserKey is null");
            Assert.IsTrue(m.ProviderUserKey is Guid, "ProviderUserKey is not a Guid");

            SafeDB.DropAll();

            // assert that the User object is in the database as well
            using (
                IObjectContainer db =
                    Db4oFactory.OpenFile(connectionStringStore.GetConnectionString("connectionStringName")))
            {
                IList<User> results = db.Query<User>(delegate(User user) { return (user.Username == "username"); });

                Assert.AreEqual(1, results.Count);

                User found = results[0];
                Assert.AreEqual("username", found.Username);
                Assert.AreEqual("email@email.com", found.Email);
                Assert.AreEqual(m.ProviderUserKey, found.PKID);
            }
        }

        [Test]
        public void DeleteUser()
        {
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, guid1,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, guid2,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, guid3,
                                out status);

            MembershipUser user = provider.GetUser(guid1, false);
            Assert.IsNotNull(user, "should not be null 1");
            user = provider.GetUser(guid2, false);
            Assert.IsNotNull(user, "should not be null 2");
            user = provider.GetUser(guid3, false);
            Assert.IsNotNull(user, "should not be null 3");

            provider.DeleteUser("username2", true);

            user = provider.GetUser(guid1, false);
            Assert.IsNotNull(user, "should not be null 4");
            user = provider.GetUser(guid2, false);
            Assert.IsNull(user, "should be null");
            user = provider.GetUser(guid3, false);
            Assert.IsNotNull(user, "should not be null 6");
        }

        [Test]
        public void FindUserByEmail()
        {
            int totalRecords;
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            Guid guid4 = Guid.NewGuid();
            Guid guid5 = Guid.NewGuid();
            Guid guid6 = Guid.NewGuid();
            Guid guid7 = Guid.NewGuid();
            provider.CreateUser("BADusername1", "password1", "BADemail@email.com1", "passwordQ1", "passwordA1", true,
                                guid1, out status);
            provider.CreateUser("BADusername2", "password2", "BADemail@email.com2", "passwordQ2", "passwordA2", true,
                                guid2, out status);
            provider.CreateUser("BATusername3", "password3", "BATemail@email.com3", "passwordQ3", "passwordA3", true,
                                guid3, out status);
            provider.CreateUser("BATusername4", "password4", "BATemail@email.com4", "passwordQ4", "passwordA4", true,
                                guid4, out status);
            provider.CreateUser("CATusername5", "password5", "CATemail@email.com5", "passwordQ5", "passwordA5", true,
                                guid5, out status);
            provider.CreateUser("CATusername6", "password6", "CATemail@email.com6", "passwordQ6", "passwordA6", true,
                                guid6, out status);
            provider.CreateUser("CATusername7", "password7", "CATemail@email.com7", "passwordQ7", "passwordA7", true,
                                guid7, out status);

            MembershipUserCollection result = provider.FindUsersByEmail("email@email.com", 0, 100, out totalRecords);
            Assert.AreEqual(7, result.Count, "wrong Count 1");
            Assert.AreEqual("BADusername1", result["BADusername1"].UserName, "wrong username1 1");
            Assert.AreEqual("BADusername2", result["BADusername2"].UserName, "wrong username2 1");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 1");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 1");
            Assert.AreEqual("CATusername5", result["CATusername5"].UserName, "wrong username5 1");
            Assert.AreEqual("CATusername6", result["CATusername6"].UserName, "wrong username6 1");
            Assert.AreEqual("CATusername7", result["CATusername7"].UserName, "wrong username7 1");

            result = provider.FindUsersByEmail("email@email.com", 1, 2, out totalRecords);
            Assert.AreEqual(2, result.Count, "wrong Count 2");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 2");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 2");
        }

        [Test]
        public void FindUserByName()
        {
            int totalRecords;
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            Guid guid4 = Guid.NewGuid();
            Guid guid5 = Guid.NewGuid();
            Guid guid6 = Guid.NewGuid();
            Guid guid7 = Guid.NewGuid();
            provider.CreateUser("BADusername1", "password1", "BADemail@email.com1", "passwordQ1", "passwordA1", true,
                                guid1, out status);
            provider.CreateUser("BADusername2", "password2", "BADemail@email.com2", "passwordQ2", "passwordA2", true,
                                guid2, out status);
            provider.CreateUser("BATusername3", "password3", "BATemail@email.com3", "passwordQ3", "passwordA3", true,
                                guid3, out status);
            provider.CreateUser("BATusername4", "password4", "BATemail@email.com4", "passwordQ4", "passwordA4", true,
                                guid4, out status);
            provider.CreateUser("CATusername5", "password5", "CATemail@email.com5", "passwordQ5", "passwordA5", true,
                                guid5, out status);
            provider.CreateUser("CATusername6", "password6", "CATemail@email.com6", "passwordQ6", "passwordA6", true,
                                guid6, out status);
            provider.CreateUser("CATusername7", "password7", "CATemail@email.com7", "passwordQ7", "passwordA7", true,
                                guid7, out status);

            MembershipUserCollection result = provider.FindUsersByName("username", 0, 100, out totalRecords);
            Assert.AreEqual(7, result.Count, "wrong Count 1");
            Assert.AreEqual("BADusername1", result["BADusername1"].UserName, "wrong username1 1");
            Assert.AreEqual("BADusername2", result["BADusername2"].UserName, "wrong username2 1");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 1");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 1");
            Assert.AreEqual("CATusername5", result["CATusername5"].UserName, "wrong username5 1");
            Assert.AreEqual("CATusername6", result["CATusername6"].UserName, "wrong username6 1");
            Assert.AreEqual("CATusername7", result["CATusername7"].UserName, "wrong username7 1");

            result = provider.FindUsersByName("username", 1, 2, out totalRecords);
            Assert.AreEqual(2, result.Count, "wrong Count 2");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 2");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 2");

            result = provider.FindUsersByName("username", 3, 2, out totalRecords);
            Assert.AreEqual(1, result.Count, "wrong Count 3");
            Assert.AreEqual("CATusername7", result["CATusername7"].UserName, "wrong username7 3");

            result = provider.FindUsersByName("BAT", 0, 100, out totalRecords);
            Assert.AreEqual(2, result.Count, "wrong Count 4");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 4");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 4");

            result = provider.FindUsersByName("BAT", 2, 2, out totalRecords);
            Assert.AreEqual(0, result.Count, "wrong Count 5");

            result = provider.FindUsersByName("foo", 0, 100, out totalRecords);
            Assert.AreEqual(0, result.Count, "wrong Count 6");
        }

        [Test]
        public void GetAllUsers()
        {
            int totalRecords;
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            Guid guid4 = Guid.NewGuid();
            Guid guid5 = Guid.NewGuid();
            Guid guid6 = Guid.NewGuid();
            Guid guid7 = Guid.NewGuid();
            provider.CreateUser("BADusername1", "password1", "BADemail@email.com1", "passwordQ1", "passwordA1", true,
                                guid1, out status);
            provider.CreateUser("BADusername2", "password2", "BADemail@email.com2", "passwordQ2", "passwordA2", true,
                                guid2, out status);
            provider.CreateUser("BATusername3", "password3", "BATemail@email.com3", "passwordQ3", "passwordA3", true,
                                guid3, out status);
            provider.CreateUser("BATusername4", "password4", "BATemail@email.com4", "passwordQ4", "passwordA4", true,
                                guid4, out status);
            provider.CreateUser("CATusername5", "password5", "CATemail@email.com5", "passwordQ5", "passwordA5", true,
                                guid5, out status);
            provider.CreateUser("CATusername6", "password6", "CATemail@email.com6", "passwordQ6", "passwordA6", true,
                                guid6, out status);
            provider.CreateUser("CATusername7", "password7", "CATemail@email.com7", "passwordQ7", "passwordA7", true,
                                guid7, out status);

            MembershipUserCollection result = provider.GetAllUsers(0, 100, out totalRecords);
            Assert.AreEqual(7, result.Count, "wrong Count 1");
            Assert.AreEqual("BADusername1", result["BADusername1"].UserName, "wrong username1 1");
            Assert.AreEqual("BADusername2", result["BADusername2"].UserName, "wrong username2 1");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 1");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 1");
            Assert.AreEqual("CATusername5", result["CATusername5"].UserName, "wrong username5 1");
            Assert.AreEqual("CATusername6", result["CATusername6"].UserName, "wrong username6 1");
            Assert.AreEqual("CATusername7", result["CATusername7"].UserName, "wrong username7 1");
        }

        [Test]
        public void GetNumberOfUsersOnline()
        {
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, guid1,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, guid2,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, guid3,
                                out status);

            int result = provider.GetNumberOfUsersOnline();
            Assert.AreEqual(3, result, "wrong count 1");

            SafeDB.DropAll();

            using (
                IObjectContainer db =
                    Db4oFactory.OpenFile(connectionStringStore.GetConnectionString("connectionstringname")))
            {
                IObjectSet results = db.Query(typeof (User));
                foreach (User user in results)
                {
                    user.LastActivityDate = DateTime.Now.AddDays(-1.0);
                    user.LastLoginDate = DateTime.Now.AddDays(-1.0);
                    db.Store(user);
                }
            }

            result = provider.GetNumberOfUsersOnline();
            Assert.AreEqual(0, result, "wrong count 2");

            provider.GetUser("username1", false);

            result = provider.GetNumberOfUsersOnline();
            Assert.AreEqual(0, result, "wrong count 3");

            provider.GetUser("username1", true);

            result = provider.GetNumberOfUsersOnline();
            Assert.AreEqual(1, result, "wrong count 4");
        }

        [Test]
        public void GetPassword()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            string result = provider.GetPassword("username1", "passwordA1");
            Assert.AreEqual("password1", result, "wrong Password retrieved");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "The supplied user name is not found.")]
        public void GetPassword_BadUsername()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.GetPassword("blarf", "blarf");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "The supplied user is locked out.")]
        public void GetPassword_LockedOut()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);

            for (int i = 0; i < 4; i++)
                provider.ValidateUser("username1", "blarf");

            provider.GetPassword("username1", "");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "Incorrect password answer.")]
        public void GetPassword_WrongAnswer()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.GetPassword("username1", "blarf");
        }

        [Test]
        public void GetUser()
        {
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, guid1,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, guid2,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, guid3,
                                out status);

            MembershipUser user = provider.GetUser(guid2, false);
            Assert.AreEqual("username2", user.UserName, "wrong Username");
            Assert.AreEqual("email@email.com2", user.Email, "wrong Email");
            Assert.AreEqual("passwordQ2", user.PasswordQuestion, "wrong PasswordQuestion");
            Assert.AreEqual(true, user.IsApproved, "wrong IsApproved");
            Assert.AreEqual(false, user.IsLockedOut, "wrong IsLockedOut");
        }

        [Test]
        public void GetUserNameByEmail()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            string result = provider.GetUserNameByEmail("blarf");
            Assert.AreEqual("", result, "should not return a username");
            result = provider.GetUserNameByEmail("email@email.com1");
            Assert.AreEqual("username1", result, "should return the username");
        }

        [Test]
        public void Initialize()
        {
            Assert.AreEqual("db4otest", provider.ApplicationName, "wrong ApplicationName");
            Assert.AreEqual(true, provider.EnablePasswordReset, "wrong EnablePasswordReset");
            Assert.AreEqual(true, provider.EnablePasswordRetrieval, "wrong EnablePasswordRetrieval");
            Assert.AreEqual(3, provider.MaxInvalidPasswordAttempts, "wrong MaxInvalidPasswordAttempts");
            Assert.AreEqual(0, provider.MinRequiredNonAlphanumericCharacters,
                            "wrong MinRequiredNonAlphanumericCharacters");
            Assert.AreEqual(5, provider.MinRequiredPasswordLength, "wrong MinRequiredPasswordLength");
            Assert.AreEqual(5, provider.PasswordAttemptWindow, "wrong PasswordAttemptWindow");
            Assert.AreEqual(MembershipPasswordFormat.Clear, provider.PasswordFormat, "wrong PasswordFormat");
            Assert.AreEqual("", provider.PasswordStrengthRegularExpression, "wrong PasswordStrengthRegularExpression");
            Assert.AreEqual(true, provider.RequiresQuestionAndAnswer, "wrong RequiresQuestionAndAnswer");
            Assert.AreEqual(true, provider.RequiresUniqueEmail, "wrong RequiresUniqueEmail");
        }

        [Test]
        public void ResetPassword()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);

            bool test = provider.ValidateUser("username1", "password1");
            Assert.AreEqual(true, test, "old password should validate");

            string newPassword = provider.ResetPassword("username1", "passwordA1");

            test = provider.ValidateUser("username1", "password1");
            Assert.AreEqual(false, test, "old password should NOT validate");

            test = provider.ValidateUser("username1", newPassword);
            Assert.AreEqual(true, test, "new password should validate");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "The supplied user is locked out.")]
        public void ResetPassword_UserLockedOut()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            for (int i = 0; i < 10; i++)
                provider.ValidateUser("username1", "foo");
            provider.ResetPassword("username1", "passwordA1");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "Password answer required for password reset.")]
        public void ResetPassword_WrongPasswordAnswer()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.ResetPassword("username1", "");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "The supplied user name is not found.")]
        public void ResetPassword_WrongUsername()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.ResetPassword("foo", "bar");
        }

        [Test]
        public void UnlockUser()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);

            for (int i = 0; i < 4; i++)
                provider.ValidateUser("username1", "blarf");

            bool result = provider.UnlockUser("blarf");
            Assert.IsFalse(result, "Should have failed");
            provider.UnlockUser("username1");
            Assert.IsFalse(result, "Should have succeeded");
            provider.GetPassword("username1", "passwordA1"); // should NOT throw exception since now unlocked
        }

        [Test]
        public void UpdateUser()
        {
            MembershipCreateStatus status;
            MembershipUser user =
                provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                    out status);

            Assert.AreEqual("username1", user.UserName, "wrong Username");
            Assert.AreEqual("email@email.com1", user.Email, "wrong Email");
            Assert.AreEqual("", user.Comment, "wrong Comment");
            Assert.AreEqual("passwordQ1", user.PasswordQuestion, "wrong PasswordQuestion");
            Assert.AreEqual(true, user.IsApproved, "wrong IsApproved");
            Assert.AreEqual(false, user.IsLockedOut, "wrong IsLockedOut");

            user.Email = "foo";
            user.Comment = "bar";
            user.IsApproved = false;
            provider.UpdateUser(user);

            user = provider.GetUser("username1", false);

            Assert.AreEqual("username1", user.UserName, "wrong Username after change");
            Assert.AreEqual("foo", user.Email, "wrong Email after change");
            Assert.AreEqual("bar", user.Comment, "wrong Comment");
            Assert.AreEqual(false, user.IsApproved, "wrong IsApproved after change");
        }

        [Test]
        public void ValidateUser()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, null,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, null,
                                out status);

            bool test;

            test = provider.ValidateUser("username1", "password1");
            Assert.IsTrue(test, "failure 1");
            test = provider.ValidateUser("username1", "password2");
            Assert.IsFalse(test, "failure 2");
            test = provider.ValidateUser("username1", "password3");
            Assert.IsFalse(test, "failure 3");
            test = provider.ValidateUser("username2", "password1");
            Assert.IsFalse(test, "failure 4");
            test = provider.ValidateUser("username2", "password2");
            Assert.IsTrue(test, "failure 5");
            test = provider.ValidateUser("username2", "password3");
            Assert.IsFalse(test, "failure 6");
            test = provider.ValidateUser("username3", "password1");
            Assert.IsFalse(test, "failure 7");
            test = provider.ValidateUser("username3", "password2");
            Assert.IsFalse(test, "failure 8");
            test = provider.ValidateUser("username3", "password3");
            Assert.IsTrue(test, "failure 9");
        }
    }

    [TestFixture]
    public class db4oMembershipProviderTestsWhenHashed
    {
        #region Setup/Teardown

        [SetUp]
        public void TestSetUp()
        {
            config = new NameValueCollection();

            config.Add("connectionStringName", "connectionstringname");
            config.Add("ApplicationName", "db4otest");
            config.Add("EnablePasswordReset", "true");
            config.Add("EnablePasswordRetrieval", "true");
            config.Add("MaxInvalidPasswordAttempts", "3");
            config.Add("MinRequiredNonAlphanumericCharacters", "0");
            config.Add("MinRequiredPasswordLength", "5");
            config.Add("PasswordAttemptWindow", "5");
            config.Add("PasswordFormat", "Hashed");
            config.Add("PasswordStrengthRegularExpression", "");
            config.Add("RequiresQuestionAndAnswer", "true");
            config.Add("RequiresUniqueEmail", "true");

            connectionStringStore = new MockConnectionStringStore();
            provider = new db4oMembershipProvider(connectionStringStore, new MockValidationKeyInfo());
            provider.Initialize("db4otest", config);

            // unit test project is a library project, so web.config is ignored, so no way to specify a provider
            // instead, custom provider is forced into system using this hack found at http://gigablast.com/get?d=66151861944
            SetReadWrite();
            Membership.Providers.Add(provider);
            Membership.Providers.SetReadOnly();
        }

        [TearDown]
        public void TestTearDown()
        {
            SetReadWrite();
            Membership.Providers.Remove(provider.Name);
            Membership.Providers.SetReadOnly();
            SafeDB.DropAll();
            File.Delete(MockConnectionStringStore.DBFileName);
            provider = null;
        }

        #endregion

        private NameValueCollection config;
        private db4oMembershipProvider provider;
        private IConnectionStringStore connectionStringStore;

        private void SetReadWrite()
        {
            typeof(ProviderCollection)
                .GetField("_ReadOnly", BindingFlags.Instance | BindingFlags.NonPublic)
                .SetValue(Membership.Providers, false);
        }

        [Test]
        public void ChangePassword()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, null,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, null,
                                out status);

            bool result = provider.ChangePassword("foo", "password2", "newpassword");
            Assert.IsFalse(result, "ChangePassword should not have succeeded");

            result = provider.ChangePassword("username2", "foo", "newpassword");
            Assert.IsFalse(result, "ChangePassword should not have succeeded");

            result = provider.ChangePassword("username2", "password2", "newpassword");
            Assert.IsTrue(result, "ChangePassword failed");

            result = provider.ChangePassword("username2", "newpassword", "newnewpassword");
            Assert.IsTrue(result, "ChangePassword failed when changing password again");
        }

        [Test]
        public void ChangePasswordQuestionAndAnswer()
        {
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, guid1,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, guid2,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, guid3,
                                out status);

            bool result = provider.ChangePasswordQuestionAndAnswer("username1", "foo", "bar", "quux");
            Assert.AreEqual(false, result, "should have failed");

            result = provider.ChangePasswordQuestionAndAnswer("username1", "password1", "bar", "quux");
            Assert.AreEqual(true, result, "should have succeeded 1");

            string newPassword = provider.ResetPassword("username1", "quux");

            result = provider.ChangePasswordQuestionAndAnswer("username1", newPassword, "abc", "def");
            Assert.AreEqual(true, result, "should have succeeded 2");
        }

        [Test]
        public void CreateUser()
        {
            MembershipCreateStatus status;
            MembershipUser m =
                provider.CreateUser("username", "password", "email@email.com", "passwordQ1", "passwordA1", true, null,
                                    out status);
            Assert.AreEqual(MembershipCreateStatus.Success, status, "status not Success");
            Assert.AreEqual("username", m.UserName, "wrong Username");
            Assert.AreEqual("email@email.com", m.Email, "wrong Email");
            Assert.AreEqual(true, m.IsApproved, "wrong IsApproved");
            Assert.AreEqual("passwordQ1", m.PasswordQuestion, "wrong PasswordQuestion");
            Assert.IsNotNull(m.ProviderUserKey, "ProviderUserKey is null");
            Assert.IsTrue(m.ProviderUserKey is Guid, "ProviderUserKey is not a Guid");

            SafeDB.DropAll();

            // assert that the User object is in the database as well
            using (
                IObjectContainer db =
                    Db4oFactory.OpenFile(connectionStringStore.GetConnectionString("connectionStringName")))
            {
                IList<User> results = db.Query<User>(delegate(User user) { return (user.Username == "username"); });

                Assert.AreEqual(1, results.Count);

                User found = results[0];
                Assert.AreEqual("username", found.Username);
                Assert.AreEqual("email@email.com", found.Email);
                Assert.AreEqual(m.ProviderUserKey, found.PKID);
            }
        }

        [Test]
        public void DeleteUser()
        {
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, guid1,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, guid2,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, guid3,
                                out status);

            MembershipUser user = provider.GetUser(guid1, false);
            Assert.IsNotNull(user, "should not be null 1");
            user = provider.GetUser(guid2, false);
            Assert.IsNotNull(user, "should not be null 2");
            user = provider.GetUser(guid3, false);
            Assert.IsNotNull(user, "should not be null 3");

            provider.DeleteUser("username2", true);

            user = provider.GetUser(guid1, false);
            Assert.IsNotNull(user, "should not be null 4");
            user = provider.GetUser(guid2, false);
            Assert.IsNull(user, "should be null");
            user = provider.GetUser(guid3, false);
            Assert.IsNotNull(user, "should not be null 6");
        }

        [Test]
        public void FindUserByEmail()
        {
            int totalRecords;
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            Guid guid4 = Guid.NewGuid();
            Guid guid5 = Guid.NewGuid();
            Guid guid6 = Guid.NewGuid();
            Guid guid7 = Guid.NewGuid();
            provider.CreateUser("BADusername1", "password1", "BADemail@email.com1", "passwordQ1", "passwordA1", true,
                                guid1, out status);
            provider.CreateUser("BADusername2", "password2", "BADemail@email.com2", "passwordQ2", "passwordA2", true,
                                guid2, out status);
            provider.CreateUser("BATusername3", "password3", "BATemail@email.com3", "passwordQ3", "passwordA3", true,
                                guid3, out status);
            provider.CreateUser("BATusername4", "password4", "BATemail@email.com4", "passwordQ4", "passwordA4", true,
                                guid4, out status);
            provider.CreateUser("CATusername5", "password5", "CATemail@email.com5", "passwordQ5", "passwordA5", true,
                                guid5, out status);
            provider.CreateUser("CATusername6", "password6", "CATemail@email.com6", "passwordQ6", "passwordA6", true,
                                guid6, out status);
            provider.CreateUser("CATusername7", "password7", "CATemail@email.com7", "passwordQ7", "passwordA7", true,
                                guid7, out status);

            MembershipUserCollection result = provider.FindUsersByEmail("email@email.com", 0, 100, out totalRecords);
            Assert.AreEqual(7, result.Count, "wrong Count 1");
            Assert.AreEqual("BADusername1", result["BADusername1"].UserName, "wrong username1 1");
            Assert.AreEqual("BADusername2", result["BADusername2"].UserName, "wrong username2 1");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 1");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 1");
            Assert.AreEqual("CATusername5", result["CATusername5"].UserName, "wrong username5 1");
            Assert.AreEqual("CATusername6", result["CATusername6"].UserName, "wrong username6 1");
            Assert.AreEqual("CATusername7", result["CATusername7"].UserName, "wrong username7 1");

            result = provider.FindUsersByEmail("email@email.com", 1, 2, out totalRecords);
            Assert.AreEqual(2, result.Count, "wrong Count 2");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 2");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 2");
        }

        [Test]
        public void FindUserByName()
        {
            int totalRecords;
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            Guid guid4 = Guid.NewGuid();
            Guid guid5 = Guid.NewGuid();
            Guid guid6 = Guid.NewGuid();
            Guid guid7 = Guid.NewGuid();
            provider.CreateUser("BADusername1", "password1", "BADemail@email.com1", "passwordQ1", "passwordA1", true,
                                guid1, out status);
            provider.CreateUser("BADusername2", "password2", "BADemail@email.com2", "passwordQ2", "passwordA2", true,
                                guid2, out status);
            provider.CreateUser("BATusername3", "password3", "BATemail@email.com3", "passwordQ3", "passwordA3", true,
                                guid3, out status);
            provider.CreateUser("BATusername4", "password4", "BATemail@email.com4", "passwordQ4", "passwordA4", true,
                                guid4, out status);
            provider.CreateUser("CATusername5", "password5", "CATemail@email.com5", "passwordQ5", "passwordA5", true,
                                guid5, out status);
            provider.CreateUser("CATusername6", "password6", "CATemail@email.com6", "passwordQ6", "passwordA6", true,
                                guid6, out status);
            provider.CreateUser("CATusername7", "password7", "CATemail@email.com7", "passwordQ7", "passwordA7", true,
                                guid7, out status);

            MembershipUserCollection result = provider.FindUsersByName("username", 0, 100, out totalRecords);
            Assert.AreEqual(7, result.Count, "wrong Count 1");
            Assert.AreEqual("BADusername1", result["BADusername1"].UserName, "wrong username1 1");
            Assert.AreEqual("BADusername2", result["BADusername2"].UserName, "wrong username2 1");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 1");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 1");
            Assert.AreEqual("CATusername5", result["CATusername5"].UserName, "wrong username5 1");
            Assert.AreEqual("CATusername6", result["CATusername6"].UserName, "wrong username6 1");
            Assert.AreEqual("CATusername7", result["CATusername7"].UserName, "wrong username7 1");

            result = provider.FindUsersByName("username", 1, 2, out totalRecords);
            Assert.AreEqual(2, result.Count, "wrong Count 2");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 2");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 2");

            result = provider.FindUsersByName("username", 3, 2, out totalRecords);
            Assert.AreEqual(1, result.Count, "wrong Count 3");
            Assert.AreEqual("CATusername7", result["CATusername7"].UserName, "wrong username7 3");

            result = provider.FindUsersByName("BAT", 0, 100, out totalRecords);
            Assert.AreEqual(2, result.Count, "wrong Count 4");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 4");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 4");

            result = provider.FindUsersByName("BAT", 2, 2, out totalRecords);
            Assert.AreEqual(0, result.Count, "wrong Count 5");

            result = provider.FindUsersByName("foo", 0, 100, out totalRecords);
            Assert.AreEqual(0, result.Count, "wrong Count 6");
        }

        [Test]
        public void GetAllUsers()
        {
            int totalRecords;
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            Guid guid4 = Guid.NewGuid();
            Guid guid5 = Guid.NewGuid();
            Guid guid6 = Guid.NewGuid();
            Guid guid7 = Guid.NewGuid();
            provider.CreateUser("BADusername1", "password1", "BADemail@email.com1", "passwordQ1", "passwordA1", true,
                                guid1, out status);
            provider.CreateUser("BADusername2", "password2", "BADemail@email.com2", "passwordQ2", "passwordA2", true,
                                guid2, out status);
            provider.CreateUser("BATusername3", "password3", "BATemail@email.com3", "passwordQ3", "passwordA3", true,
                                guid3, out status);
            provider.CreateUser("BATusername4", "password4", "BATemail@email.com4", "passwordQ4", "passwordA4", true,
                                guid4, out status);
            provider.CreateUser("CATusername5", "password5", "CATemail@email.com5", "passwordQ5", "passwordA5", true,
                                guid5, out status);
            provider.CreateUser("CATusername6", "password6", "CATemail@email.com6", "passwordQ6", "passwordA6", true,
                                guid6, out status);
            provider.CreateUser("CATusername7", "password7", "CATemail@email.com7", "passwordQ7", "passwordA7", true,
                                guid7, out status);

            MembershipUserCollection result = provider.GetAllUsers(0, 100, out totalRecords);
            Assert.AreEqual(7, result.Count, "wrong Count 1");
            Assert.AreEqual("BADusername1", result["BADusername1"].UserName, "wrong username1 1");
            Assert.AreEqual("BADusername2", result["BADusername2"].UserName, "wrong username2 1");
            Assert.AreEqual("BATusername3", result["BATusername3"].UserName, "wrong username3 1");
            Assert.AreEqual("BATusername4", result["BATusername4"].UserName, "wrong username4 1");
            Assert.AreEqual("CATusername5", result["CATusername5"].UserName, "wrong username5 1");
            Assert.AreEqual("CATusername6", result["CATusername6"].UserName, "wrong username6 1");
            Assert.AreEqual("CATusername7", result["CATusername7"].UserName, "wrong username7 1");
        }

        [Test]
        public void GetNumberOfUsersOnline()
        {
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, guid1,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, guid2,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, guid3,
                                out status);

            int result = provider.GetNumberOfUsersOnline();
            Assert.AreEqual(3, result, "wrong count 1");

            SafeDB.DropAll();

            using (
                IObjectContainer db =
                    Db4oFactory.OpenFile(connectionStringStore.GetConnectionString("connectionstringname")))
            {
                IObjectSet results = db.Query(typeof(User));
                foreach (User user in results)
                {
                    user.LastActivityDate = DateTime.Now.AddDays(-1.0);
                    user.LastLoginDate = DateTime.Now.AddDays(-1.0);
                    db.Store(user);
                }
            }

            result = provider.GetNumberOfUsersOnline();
            Assert.AreEqual(0, result, "wrong count 2");

            provider.GetUser("username1", false);

            result = provider.GetNumberOfUsersOnline();
            Assert.AreEqual(0, result, "wrong count 3");

            provider.GetUser("username1", true);

            result = provider.GetNumberOfUsersOnline();
            Assert.AreEqual(1, result, "wrong count 4");
        }

        [Test]
        public void GetUser()
        {
            MembershipCreateStatus status;
            Guid guid1 = Guid.NewGuid();
            Guid guid2 = Guid.NewGuid();
            Guid guid3 = Guid.NewGuid();
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, guid1,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, guid2,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, guid3,
                                out status);

            MembershipUser user = provider.GetUser(guid2, false);
            Assert.AreEqual("username2", user.UserName, "wrong Username");
            Assert.AreEqual("email@email.com2", user.Email, "wrong Email");
            Assert.AreEqual("passwordQ2", user.PasswordQuestion, "wrong PasswordQuestion");
            Assert.AreEqual(true, user.IsApproved, "wrong IsApproved");
            Assert.AreEqual(false, user.IsLockedOut, "wrong IsLockedOut");
        }

        [Test]
        public void GetUserNameByEmail()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            string result = provider.GetUserNameByEmail("blarf");
            Assert.AreEqual("", result, "should not return a username");
            result = provider.GetUserNameByEmail("email@email.com1");
            Assert.AreEqual("username1", result, "should return the username");
        }

        [Test]
        public void Initialize()
        {
            Assert.AreEqual("db4otest", provider.ApplicationName, "wrong ApplicationName");
            Assert.AreEqual(true, provider.EnablePasswordReset, "wrong EnablePasswordReset");
            Assert.AreEqual(true, provider.EnablePasswordRetrieval, "wrong EnablePasswordRetrieval");
            Assert.AreEqual(3, provider.MaxInvalidPasswordAttempts, "wrong MaxInvalidPasswordAttempts");
            Assert.AreEqual(0, provider.MinRequiredNonAlphanumericCharacters,
                            "wrong MinRequiredNonAlphanumericCharacters");
            Assert.AreEqual(5, provider.MinRequiredPasswordLength, "wrong MinRequiredPasswordLength");
            Assert.AreEqual(5, provider.PasswordAttemptWindow, "wrong PasswordAttemptWindow");
            Assert.AreEqual(MembershipPasswordFormat.Hashed, provider.PasswordFormat, "wrong PasswordFormat");
            Assert.AreEqual("", provider.PasswordStrengthRegularExpression, "wrong PasswordStrengthRegularExpression");
            Assert.AreEqual(true, provider.RequiresQuestionAndAnswer, "wrong RequiresQuestionAndAnswer");
            Assert.AreEqual(true, provider.RequiresUniqueEmail, "wrong RequiresUniqueEmail");
        }

        [Test]
        public void ResetPassword()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);

            bool test = provider.ValidateUser("username1", "password1");
            Assert.AreEqual(true, test, "old password should validate");

            string newPassword = provider.ResetPassword("username1", "passwordA1");

            test = provider.ValidateUser("username1", "password1");
            Assert.AreEqual(false, test, "old password should NOT validate");

            test = provider.ValidateUser("username1", newPassword);
            Assert.AreEqual(true, test, "new password should validate");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "The supplied user is locked out.")]
        public void ResetPassword_UserLockedOut()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            for (int i = 0; i < 10; i++)
                provider.ValidateUser("username1", "foo");
            provider.ResetPassword("username1", "passwordA1");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "Password answer required for password reset.")]
        public void ResetPassword_WrongPasswordAnswer()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.ResetPassword("username1", "");
        }

        [Test]
        [ExpectedException(ExpectedMessage = "The supplied user name is not found.")]
        public void ResetPassword_WrongUsername()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.ResetPassword("foo", "bar");
        }

        [Test]
        public void UnlockUser()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);

            for (int i = 0; i < 4; i++)
                provider.ValidateUser("username1", "blarf");

            bool result = provider.UnlockUser("blarf");
            Assert.IsFalse(result, "Should have failed");
            provider.UnlockUser("username1");
            Assert.IsFalse(result, "Should have succeeded");
        }

        [Test]
        public void UpdateUser()
        {
            MembershipCreateStatus status;
            MembershipUser user =
                provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                    out status);

            Assert.AreEqual("username1", user.UserName, "wrong Username");
            Assert.AreEqual("email@email.com1", user.Email, "wrong Email");
            Assert.AreEqual("", user.Comment, "wrong Comment");
            Assert.AreEqual("passwordQ1", user.PasswordQuestion, "wrong PasswordQuestion");
            Assert.AreEqual(true, user.IsApproved, "wrong IsApproved");
            Assert.AreEqual(false, user.IsLockedOut, "wrong IsLockedOut");

            user.Email = "foo";
            user.Comment = "bar";
            user.IsApproved = false;
            provider.UpdateUser(user);

            user = provider.GetUser("username1", false);

            Assert.AreEqual("username1", user.UserName, "wrong Username after change");
            Assert.AreEqual("foo", user.Email, "wrong Email after change");
            Assert.AreEqual("bar", user.Comment, "wrong Comment");
            Assert.AreEqual(false, user.IsApproved, "wrong IsApproved after change");
        }

        [Test]
        public void ValidateUser()
        {
            MembershipCreateStatus status;
            provider.CreateUser("username1", "password1", "email@email.com1", "passwordQ1", "passwordA1", true, null,
                                out status);
            provider.CreateUser("username2", "password2", "email@email.com2", "passwordQ2", "passwordA2", true, null,
                                out status);
            provider.CreateUser("username3", "password3", "email@email.com3", "passwordQ3", "passwordA3", true, null,
                                out status);

            bool test;

            test = provider.ValidateUser("username1", "password1");
            Assert.IsTrue(test, "failure 1");
            test = provider.ValidateUser("username1", "password2");
            Assert.IsFalse(test, "failure 2");
            test = provider.ValidateUser("username1", "password3");
            Assert.IsFalse(test, "failure 3");
            test = provider.ValidateUser("username2", "password1");
            Assert.IsFalse(test, "failure 4");
            test = provider.ValidateUser("username2", "password2");
            Assert.IsTrue(test, "failure 5");
            test = provider.ValidateUser("username2", "password3");
            Assert.IsFalse(test, "failure 6");
            test = provider.ValidateUser("username3", "password1");
            Assert.IsFalse(test, "failure 7");
            test = provider.ValidateUser("username3", "password2");
            Assert.IsFalse(test, "failure 8");
            test = provider.ValidateUser("username3", "password3");
            Assert.IsTrue(test, "failure 9");
        }
    }
}

#pragma warning restore 612,618